home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
Xprof
/
xprof
/
parse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
18KB
|
625 lines
/*==================================================================
* File : parse.c
* Package: Xprof
*
* Author : Aloke Gupta.
*
* (C) Copyright 1992, Aloke Gupta.
*==================================================================*/
/* parse.c
*
* Parse the input file containing information on sizes and speeds of
* the Xlib requests
*
* Each input line is of the form:
* Request_Name Attr_1=<> ... Attr_N=< > (Size_1, Speed_1) ... (Size_N, Speed_N)
*
* Multiple specifications may be given for each request, for different sizes.
* A '#' sign marks of comments. All lines that begin with a '#' are ignored and
* all characters following a '#; are ignored too.
* Functions:
* 1. parse_parameters(FILE *fp)
* 2. init_msgcost();
* 3. fill_win_cost(int index, char **strptrptr)
* 4. fill_gfx_cost(int index, char **strptrptr)
* 5. fill_txt_cost(int index, char **strptrptr)
* 6. insert_costcell(CostCell **costlist, float size, float speed)
* 7. get_request_time(int index, Xattributes *attributes)
* 8. CostCell *allocCostCell(float size, float speed)
* 9. printlist(CostCell *costlist)
* 10. get_db_linewidth_index(int lw, Install install)
* 11. get_db_closest_lw(int lw)
* 11. get_db_fontname_index(char *fontname, Install install)
*/
#include <stdio.h>
#include "common.h"
#include "profile.h"
extern MsgType RequestType[]; /* Defined in table.c */
MsgCost msgcost[MAXREQUESTS];
CostCell *allocCostCell(/* size, speed*/);
static double net_latency = 0.0; /* Network latency in milliseconds */
static double net_speed = MAXDOUBLE; /* Network speed in bytes per second */
static int linenum=0; /* linenumber in init file */
void set_net_latency(latency) double latency; { net_latency = latency; }
void set_net_speed (speed ) double speed ; { net_speed = speed ; }
double get_net_latency( ) { return net_latency ; }
double get_net_speed ( ) { return net_speed ; }
/*
* Parse the initialization file to obtain the costs of each request
*/
parse_parameters(fp)
FILE *fp;
{
char req_name[80];
char in_string[MAXSTRINGSIZE];
char *strptr, *tmpptr ;
int req_num;
double dtmp;
/*
* Initialize the msgcost array to NULLs
*/
init_msgcost();
/*
* Now scan the initialization file
*/
while( fgets(in_string, MAXSTRINGSIZE, fp) != NULL) {
linenum++;
strptr = in_string;
while (isspace(*strptr)) strptr++; /* Eat the leading white space */
if (*strptr == '#') continue; /* Ignore comment lines */
if ((tmpptr = strchr(strptr, '#')) != NULL)
*tmpptr = '\0'; /* Ignore all that follows a # */
if (sscanf(strptr, "%s", req_name) != 1)
continue;
/* Check if this is information about the network */
if (t_search(strptr, "Network Latency")) {
tmpptr = strptr + strlen("Network Latency");
if (sscanf(tmpptr, "%lf", &dtmp) != 1)
fprintf(stderr, "line %3d: Insufficient arguments\n", linenum);
else set_net_latency(dtmp);
continue;
}
if (t_search(strptr, "Network Speed")) {
tmpptr = strptr + strlen("Network Speed");
if (sscanf(tmpptr, "%lf", &dtmp) != 1)
fprintf(stderr, "line %3d: Insufficient arguments\n", linenum);
else {
if (dtmp > 0)
set_net_speed(1000.0*dtmp); /*Convert to bytes per second*/
else fprintf(stderr,"Network speed must be more than zero !!\n");
}
continue;
}
/*
* Check if this is a legal request
*/
if ((req_num = lookup_request(req_name) ) == 0) {
fprintf(stderr,"line %3d: Unknown request: %s\n",linenum,req_name);
continue;
}
/*
* Update the data structures for this request, by entering the
* request in the appropriate location.
*/
switch(RequestType[req_num].msgclass) {
case WIN:
fill_win_cost(req_num, &strptr);
break;
case GFX:
fill_gfx_cost(req_num, &strptr);
break;
case TXT:
fill_txt_cost(req_num, &strptr);
break;
default:
break;
}
}
return(0);
}
init_msgcost() {
int i, j;
for (i = 0; i < MAXREQUESTS; i++) {
switch (RequestType[i].msgclass) {
case WIN: /* Windowing request */
msgcost[i].win = NULL;
break;
case GFX: /* Graphics request */
msgcost[i].gfx = (GfxCost *) malloc(GFXSLOTS * sizeof(GfxCost));
for (j = 0; j < GFXSLOTS; j++) {
/*
msgcost[i].gfx[j].linewidth = 0;
*/
msgcost[i].gfx[j].costlist = NULL;
}
break;
case TXT: /* Graphics request */
msgcost[i].txt = (TxtCost *) malloc(TXTSLOTS * sizeof(TxtCost));
for (j = 0; j < TXTSLOTS; j++) {
/*
msgcost[i].txt[j].fontname = NULL;
*/
msgcost[i].txt[j].costlist = NULL;
}
break;
default:
fprintf(stderr,"init_msgcost: Unknown Message Class: %d for message %s\n",
RequestType[i].msgclass, RequestType[i].name);
break;
}
}
}
fill_win_cost(req_num, strptrptr)
int req_num;
char **strptrptr; /* Address of the pointer to the string */
{
float size, speed;
/*
* First get rid of the request name
*/
while (isspace(**strptrptr)) /* Strip leading white space */
(*strptrptr)++;
while (!isspace(**strptrptr)) /* Get past request name */
(*strptrptr)++;
/* Now search for the window attributes */
/* There aren't any :-) */
/* Scan the input list of (size, speed) */
while ( (*strptrptr = strchr(*strptrptr, '(' )) != NULL) {
if (sscanf(*strptrptr, "(%f, %f)", &size, &speed) != 2) {
fprintf(stderr,"line %3d: Insufficient arguments\n",linenum);
fprintf(stderr, "\t%s\n", *strptrptr);
continue;
}
insert_costcell(&msgcost[req_num].win, size, speed);
(*strptrptr)++;
}
}
/*
* fill_gfx_cost()
* Input format expected:
* Request_Name gxmode=<GXMODE> linestyle=<LINESTYLE> fillstyle=<FILLSTYLE> \
linewidth=<LINEWIDTH> (Size_1, Speed_1) ... (Size_N, Speed_N)
*
*/
fill_gfx_cost(req_num, strptrptr)
int req_num;
char **strptrptr; /* Address of the pointer to the string */
{
int gfxindex=0;
float size, speed;
int gxmode=0, linestyle=0, fillstyle=0, linewidth=0;
int fd_all=0;
Boolean fd_gxmode=FALSE, fd_linestyle=FALSE,
fd_fillstyle=FALSE, fd_linewidth=FALSE;
/*
* First get rid of the request name
*/
while (isspace(**strptrptr)) /* Strip leading white space */
(*strptrptr)++;
while (!isspace(**strptrptr)) /* Get past request name */
(*strptrptr)++;
/* Now search for the graphics attributes */
while(fd_all < 4) {
/* Strip leading white space */
while (isspace(**strptrptr))
(*strptrptr)++;
/*
* Fill the gxmode attribute
*/
if ( (fd_gxmode == FALSE) && (t_search(*strptrptr, "gxmode=") !=0) ) {
fd_gxmode = TRUE; fd_all ++;
while (*(*strptrptr)++ != '='); /* Consume chars upto '=' */
/* Now find out exactly what gxmode it is */
if (t_search(*strptrptr, "GXclear") != 0)
gxmode = XPROF_GXCLEAR;
else if (t_search(*strptrptr, "GXand") != 0)
gxmode = XPROF_GXAND;
else if (t_search(*strptrptr, "GXandReverse") != 0)
gxmode = XPROF_GXANDREVERSE;
else if (t_search(*strptrptr, "GXcopy") != 0)
gxmode = XPROF_GXCOPY;
else if (t_search(*strptrptr, "GXandInverted") != 0)
gxmode = XPROF_GXANDINVERTED;
else if (t_search(*strptrptr, "GXnoop") != 0)
gxmode = XPROF_GXNOOP;
else if (t_search(*strptrptr, "GXxor") !=0 )
gxmode = XPROF_GXXOR;
else if (t_search(*strptrptr, "GXor") !=0 )
gxmode = XPROF_GXOR;
else if (t_search(*strptrptr, "GXnor") != 0)
gxmode = XPROF_GXNOR;
else if (t_search(*strptrptr, "GXequiv") != 0)
gxmode = XPROF_GXEQUIV;
else if (t_search(*strptrptr, "GXinvert") != 0)
gxmode = XPROF_GXINVERT;
else if (t_search(*strptrptr, "GXorReverse") != 0)
gxmode = XPROF_GXORREVERSE;
else if (t_search(*strptrptr, "GXcopyInverted") != 0)
gxmode = XPROF_GXCOPYINVERTED;
else if (t_search(*strptrptr, "GXorInverted") != 0)
gxmode = XPROF_GXORINVERTED;
else if (t_search(*strptrptr, "GXnand") != 0)
gxmode = XPROF_GXNAND;
else if (t_search(*strptrptr, "GXset") != 0)
gxmode = XPROF_GXSET;
while (!isspace(**strptrptr)) /* Get past gxmode attribute */
(*strptrptr)++;
}
/*
* Fill the linestyle attribute
*/
else
if ( (fd_linestyle == FALSE)&&(t_search(*strptrptr,"linestyle=") !=0) ){
fd_linestyle = TRUE; fd_all ++;
while (*(*strptrptr)++ != '='); /* Consume chars upto '=' */
if (t_search(*strptrptr, "LineSolid") != 0)
linestyle = XPROF_LINESOLID;
else if (t_search(*strptrptr, "LineOnOffDash") != 0)
linestyle = XPROF_LINEONOFFDASH;
else if (t_search(*strptrptr, "LineDoubleDash") != 0)
linestyle = XPROF_LINEDOUBLEDASH;
while (!isspace(**strptrptr)) /* Get past linestyle attribute */
(*strptrptr)++;
}
/*
* Fill the fillstyle attribute
*/
else
if ( (fd_fillstyle == FALSE)&&(t_search(*strptrptr, "fillstyle=")!=0)){
fd_fillstyle = TRUE; fd_all ++;
while (*(*strptrptr)++ != '='); /* Consume chars upto '=' */
if (t_search(*strptrptr, "FillSolid") != 0)
fillstyle = XPROF_FILLSOLID;
else if (t_search(*strptrptr, "FillOpaqueStippled") != 0)
fillstyle = XPROF_FILLOPAQUESTIPPLED;
else if (t_search(*strptrptr, "FillStippled") != 0)
fillstyle = XPROF_FILLSTIPPLED;
else if (t_search(*strptrptr, "FillTiled") != 0)
fillstyle = XPROF_FILLTILED;
while (!isspace(**strptrptr)) /* Get past fillstyle attribute */
(*strptrptr)++;
}
/*
* Fill the linewidth attribute
*/
else
if ( (fd_linewidth == FALSE)&&(t_search(*strptrptr, "linewidth=")!=0)){
int lw; /* actual line width */
fd_linewidth = TRUE; fd_all ++;
while (*(*strptrptr)++ != '='); /* Consume chars upto '=' */
sscanf(*strptrptr,"%d", &lw);
/* Get index of this linewidth*/
linewidth=get_db_linewidth_index(lw, INSTALL);
if (linewidth == -1) {
fprintf(stderr, "line %3d: Cannot add linewidth %d to database",
linenum, lw);
fprintf(stderr, "line %3d: %s", linenum, *strptrptr);
return;
}
while (!isspace(**strptrptr)) /* Get past linewidth attribute */
(*strptrptr)++;
}
else {
fprintf(stderr, "line %3d: Cannot parse attributes :%s\n",
linenum, *strptrptr);
fflush(stderr);
return;
}
}
gfxindex = GFXINDEX(gxmode, linestyle, fillstyle, linewidth);
/*
* Scan the input list of (size, speed)
*/
while ( (*strptrptr = strchr(*strptrptr, '(' )) != NULL) {
if (sscanf(*strptrptr, "(%f, %f)", &size, &speed) != 2) {
fprintf(stderr,"line %3d: Insufficient arguments\n",linenum);
fprintf(stderr, "\t%s\n", *strptrptr);
continue;
}
insert_costcell(&msgcost[req_num].gfx[gfxindex].costlist,size,speed);
(*strptrptr)++;
}
/*
printf("%-17s %2d\n", RequestType[req_num].name, req_num);
printf("Gfxslot = %d", gfxindex);
printlist(msgcost[req_num].gfx[gfxindex].costlist);
fflush(stdout);
*/
}
fill_txt_cost(req_num, strptrptr)
int req_num;
char **strptrptr; /* Address of the pointer to the string */
{
char buffer[MAXSTRINGSIZE];
int txtindex=0;
float size, speed;
/*
* First get rid of the request name
*/
while (isspace(**strptrptr)) /* Strip leading white space */
(*strptrptr)++;
while (!isspace(**strptrptr)) /* Get past request name */
(*strptrptr)++;
/* Now search for the text attributes */
while (isspace(**strptrptr)) /* Strip leading white space */
(*strptrptr)++;
if (t_search(*strptrptr, "fontname=") !=0 ) {
while (*(*strptrptr)++ != '='); /* Consume chars upto '=' */
sscanf(*strptrptr, "%s", buffer);
txtindex = get_db_fontname_index(buffer);
if (txtindex == -1) {
fprintf(stderr, "line %3d: Cannot add font %s to database",
linenum, buffer);
fprintf(stderr, "line %3d: %s", linenum, *strptrptr);
return;
}
}
/* Scan the input list of (size, speed) */
while ( (*strptrptr = strchr(*strptrptr, '(' )) != NULL) {
if (sscanf(*strptrptr, "(%f, %f)", &size, &speed) != 2) {
fprintf(stderr,"line %3d: Insufficient arguments\n",linenum);
fprintf(stderr, "\t%s\n", *strptrptr);
continue;
}
insert_costcell(&msgcost[req_num].txt[txtindex].costlist, size, speed);
(*strptrptr)++;
}
}
insert_costcell(costlist, size, speed)
CostCell **costlist; /* Pointer to the costlist */
float size;
float speed;
{
CostCell *newcell, *listptr;
newcell = allocCostCell(size, speed);
if (*costlist == NULL) { /* First time info seen !!*/
*costlist = newcell;
}
else { /* Insert in linked list in ascending order of size */
listptr = *costlist;
while (listptr->nextcost != NULL) { /* Traverse linked list */
if ((listptr->size <= newcell->size) &&
(listptr->nextcost->size >= newcell->size ))
break;
listptr = listptr->nextcost; /* Next item in the list */
}
/* Now insert the newcell in the list */
if (listptr->nextcost == NULL) /* End of the list */
listptr->nextcost = newcell;
else {
newcell->nextcost = listptr->nextcost;
listptr->nextcost = newcell;
}
}
}
float get_request_time(req_num, attributes)
int req_num;
Xattributes *attributes;
{
CostCell *listptr1, *listptr2;
float size1, size2, time1, time2;
int gfxindex=0, txtindex=0;
#ifdef TEST
printlist (msgcost[req_num].win);
#endif
switch(RequestType[req_num].msgclass) {
case WIN:
listptr1 = msgcost[req_num].win;
break;
case GFX:
if (attributes->gcval != NULL)
gfxindex = gc_gfxindex(stdout, req_num, attributes->gcval);
fflush(stdout);
listptr1 = msgcost[req_num].gfx[gfxindex].costlist;
break;
case TXT:
if (attributes->gcval != NULL)
txtindex = gc_fontindex(stdout, req_num, attributes->gcval);
listptr1 = msgcost[req_num].txt[txtindex].costlist;
break;
default:
break;
}
/* Empty list ? */
if (listptr1 == NULL)
return(-1.0);
/* Only one data point ? */
if (listptr1->nextcost == NULL) {
if (listptr1->size == 0)
return (1/listptr1->speed);
else
return(attributes->size / (listptr1->size * listptr1->speed));
}
/* Two or more data points available */
listptr2 = listptr1->nextcost;
while ((listptr2->nextcost != NULL)&&(listptr2->size < attributes->size) ) {
listptr1 = listptr2;
listptr2 = listptr2->nextcost;
}
if (listptr2->size == attributes->size) /* Exact match !! */
return(1.0 / listptr2->speed);
if (listptr1->size == attributes->size) /* Exact match !! */
return(1.0 / listptr1->speed);
if (listptr2->size != listptr1->size) { /* Interpolate the msmt. */
size1 = listptr1->size;
size2 = listptr2->size;
time1 = 1.0 / listptr1->speed;
time2 = 1.0 / listptr2->speed;
return(time1 + ((time2 - time1) / (size2 - size1)) * (attributes->size - size1));
}
else return((listptr2->size / attributes->size) * listptr2->speed);
}
CostCell *allocCostCell(size, speed)
float size;
float speed;
{
CostCell *newptr;
newptr = (CostCell *) malloc( sizeof(CostCell) );
newptr->size = size;
newptr->speed = speed;
newptr->nextcost = NULL;
return (newptr);
}
printlist(costlist)
CostCell *costlist;
{
int count = 0;
while (costlist !=NULL) {
if (((count % 2) == 0) && (count !=0))
printf("\n%17s "," ");
printf(" (%8.1f,%8.1f,%8.4f)", costlist->size, costlist->speed,
1000.0/costlist->speed);
costlist = costlist->nextcost;
count++;
}
printf("\n");
}
static int line_width[XPROF_LINEWIDTHS];
static int num_valid_lw=0;
int get_db_linewidth_index(lw, install)
int lw; /* Actual value of the line width */
Install install; /* Install in list if not found ? */
{
int i, retval;
for (i=0; i < num_valid_lw; i++)
if (lw == line_width[i]) return (i);
if ( (num_valid_lw == XPROF_LINEWIDTHS) || (install == NOINSTALL) )
return (-1);
retval = num_valid_lw;
line_width[num_valid_lw++] = lw;
return (retval);
}
/*
* The following function returns the line width closest to the desired one
*/
int get_db_closest_lw(lw)
int lw; /* Actual value of the line width */
{
int i, olderror=MAXINT, error, retval;
if (num_valid_lw == 0) /* List is empty */
return (-1);
for (i=0; i < num_valid_lw; i++) {
error = line_width[i] - lw;
if (error < 0)
error *= -1;
if (error < olderror) {
retval = line_width[i];
}
olderror = error;
}
return(retval);
}
static char *font_name[TXTSLOTS];
static int num_valid_fonts=0;
int get_db_fontname_index(fontname, install)
char *fontname; /* Actual name of this font */
Install install; /* Install in list if not found ? */
{
int i, retval;
for (i=0; i < num_valid_fonts; i++)
if (!strcmp(fontname, font_name[i]) )return(i);
if ( (num_valid_fonts == TXTSLOTS) || (install == NOINSTALL) )
return (-1);
retval = num_valid_fonts;
font_name[num_valid_fonts] = malloc(strlen(fontname) + 1);
strcpy(font_name[num_valid_fonts], fontname);
num_valid_fonts ++;
return (retval);
}
char *db_font_name(index)
int index;
{
if (index < num_valid_fonts)
return(font_name[index]);
else
return(NULL);
}
#ifdef TEST
main()
{
FILE *fp;
int index, size;
Xattributes attributes;
float time;
fp = fopen("test.dat", "r");
parse_parameters(fp);
while(1) {
scanf("%d %d", &index, &size);
printf("index = %d size = %d ", index, size); fflush(stdout);
attributes.size = (float) size;
time = get_request_time(index, &attributes);
printf("Time = ");
if (time == -1)
printf("N/A\n");
else printf("%.6f ms\n",time*1000);
fflush(stdout);
}
}
#endif